#ifndef __GOBJS_H
#define __GOBJS_H

#include <config.h>
#include <gapi.h>
#include <unicode.h>
#include <types.h>
#include <linux_list.h>

#define ALIGN_NONE   0x0
#define ALIGN_RIGHT  0x1
#define ALIGN_CENTER 0x2
#define ALIGN_LEFT   0x4
#define ALIGN_TOP    0x10
#define ALIGN_MIDDLE 0x20
#define ALIGN_BOTTOM 0x40

#define BUFFERED_IMAGE_AMOUNT 3
#define GOBJ_IMG_LAYER        (BUFFERED_IMAGE_AMOUNT + 3) /* text, foreground, background, buffered img x 3 */
#define BUFFERED_IMG_ALL      (BUFFERED_IMAGE_AMOUNT + 1) /* the last one is reserved for internal using */
#define TEXT_MAGIC            0x54455854   /* Used to indicate TEXT object */

#define IMG_LAYER_ALL         0
#define IMG_LAYER_BACKGROUND  1
#define IMG_LAYER_FOREGROUND  2
#define IMG_LAYER_TEXT        3
#define IMG_LAYER_BUFFERIMG0  4
#define IMG_LAYER_BUFFERIMG1  5
#define IMG_LAYER_BUFFERIMG2  6

#define GOBJ_METHOD \
    int (*setBackground)(void *, u8 *, BOOLEAN); \
    int (*setForeground)(void *, u8 *, u8); \
    int (*setBufferImage)(void *, u8 *, s8, BOOLEAN); \
    int (*setText)(void *, unicode_t *, u8, COLOR *, u8 *, u32, u8, COORD *); \
    int (*setVisible)(void *, u8, BOOLEAN); \
    int (*setActivate)(void *, BOOLEAN); \
    int (*updateBackground)(void *, u8 *, BOOLEAN); \
    int (*updateForeground)(void *, u8 *, u8); \
    int (*updateBufferImage)(void *, u8 *, s8, BOOLEAN); \
    int (*updateText)(void *, unicode_t *); \
    int (*draw)(void *); \
    int (*redraw)(void *)

/*
 * Graphic Objects Structure
 */
typedef struct {
    u32              gid;                                  /* GObj id */
    u32              pid;                                  /* GObj id in page */
    u32              x;                                    /* GObj position x */
    u32              y;                                    /* GObj position y */
    u32              width;                                /* GObj width */
    u32              height;                               /* GObj height */
    COLOR            *color;                               /* GObj Background color */
    TEXT             *text;                                /* Pointer to text obj */
    IMAGE            *foreground;                          /* Pointer to foreground image obj */
    IMAGE            *background;                          /* Pointer to background image obj */
    IMAGE            *buffered_img[BUFFERED_IMG_ALL];      /* Buffer img */
    IMAGE            *img_layer_table[GOBJ_IMG_LAYER];     /* Image layer table */
    u8               fg_align;                             /* Foreground alignment setting */
    u8               text_align;                           /* Text alignment setting */
    BOOLEAN          text_multilines;                      /* Draw text to next line while total text width is larger than GObj width */
    BOOLEAN          activate;                             /* Activate GObj ? */
    BOOLEAN          visible;                              /* GObj visible ? */
    u8               event_trigger_type;                   /* Event trigger type */
    struct list_head pg_list;                              /* This gobj belongs to the pages in this list */
    struct list_head overlapped_gobj_list;                 /* Link list for tracking overlapped gobj */
    GOBJ_METHOD;                                           /* Methods for each GObj */
    MOUSE_EVENT;                                           /* Events */
    int              (*draw_hook)(void *);                 /* Customized draw function */
    void             *private_data;                        /* Private data free for use */
} GOBJ;

/*
 * Graphic Object Link Node Structure for PAGEs
 */
typedef struct gobj_link_node {
    u32  sx, sy;       /* Sensitive area start position */
    u32  dx, dy;       /* Sensitive area end position  */
    GOBJ *gobj;        /* Point to the corresponding gobject */
    struct list_head list;
} GOBJ_LINK_NODE;

typedef struct overlapped_gobj_link_node {
    GOBJ *gobj;
    struct list_head list;
} OVERLAPPED_GOBJ_LINK_NODE;

GOBJ* CreateGObj(u32 x, u32 y, u32 width, u32 height, COLOR *color);
int DestroyGObj(GOBJ *obj);
struct list_head *__duplicate_overlapped_gobj_list(GOBJ *gobj);

#endif
